using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UI;

public class Toast : Singleton<Toast>
{
    public Transform parent;
    public GameObject prefab;
    public float moveSeed = 10;
    public float moveDistance = 100;
    Vector3 initPos;

    ObjectPool<GameObject> toastPool;

    List<CanvasGroup> toastList = new List<CanvasGroup>();
    List<CanvasGroup> removeItemList = new List<CanvasGroup>();

    float minY = 10000;
    public float toastItemHeight = 10;

    public void Start()
    {
        toastPool = new ObjectPool<GameObject>(CreatePooledItem, OnTakeFromPool, OnReturnedToPool, OnDestroyPoolObject);
        initPos = prefab.transform.localPosition;
    }

    public static void ShowToast(string msg)
    {
        Instance._ShowToast(msg);
    }

    void _ShowToast(string msg)
    {
        GameObject obj = toastPool.Get();
        obj.transform.localRotation = Quaternion.Euler(0, 0, 0);
        obj.transform.Find("Text").GetComponent<Text>().text = msg;
        toastList.Add(obj.GetComponent<CanvasGroup>());
    }

    GameObject CreatePooledItem()
    {
        var go =  GameObject.Instantiate(prefab);
        go.transform.SetParent(parent);
        return go;
    }

    // Called when an item is taken from the pool using Get
    void OnTakeFromPool(GameObject obj)
    {
        obj.GetComponent<CanvasGroup>().alpha = 1;
        
        obj.transform.localPosition = initPos;
        obj.transform.localScale = Vector3.one;
    }

    // Called when an item is returned to the pool using Release
    void OnReturnedToPool(GameObject obj)
    {
        obj.GetComponent<CanvasGroup>().alpha = 0;
    }

    // If the pool capacity is reached then any items returned will be destroyed.
    // We can control what the destroy behavior does, here we destroy the GameObject.
    void OnDestroyPoolObject(GameObject obj)
    {
        GameObject.Destroy(obj);
    }

    public void Update()
    {
        minY = 10000;
        for (int i = 0; i < toastList.Count; i++)
        {
            if (toastList[i].alpha > 0)
            {
                minY = Mathf.Min(toastList[i].transform.localPosition.y, minY);
            }
        }
        for (int i = 0; i < toastList.Count; i++)
        {
            Transform transform = toastList[i].transform;
            if (transform.localPosition.y - initPos.y >= moveDistance)
            {
                removeItemList.Add(toastList[i]);
            }
            else
            {
                if (i == 0 || i >= 1 && (toastList[i - 1].transform.localPosition.y - initPos.y - 5) >= toastItemHeight)
                {
                    transform.localPosition += moveSeed * Time.deltaTime * Vector3.up;
                }
                else
                {
                    break;
                }
            }
        }
        if (removeItemList.Count > 0)
        {
            foreach (var item in removeItemList)
            {
                toastList.Remove(item);
                toastPool.Release(item.gameObject);
            }
            removeItemList.Clear();
        }
    }

    [ContextMenu("TestToast")]
    void TestToast()
    {
        Toast.ShowToast("Test Toast 1");
        Toast.ShowToast("Test Toast 2");
        Toast.ShowToast("Test Toast 3");
    }
}